package viewbuilder;

import groovy.util.BuilderSupport;

import java.util.Map;
import java.io.Writer;
import java.io.IOException;

public class HtmlBuilderJava extends BuilderSupport {

    public static final int CLOSED_ELEMENT = 1;
    public static final int OPENED_ELEMENT = 2;
    public static final int TEXT_ELEMENT = 3;


    int state;
    Writer writer;

    public HtmlBuilderJava(Writer writer) {
        this.writer = writer;
    }

    protected void setParent(Object parent, Object child) {
    }

    protected Object createNode(Object name) {
        return createNode(name, null, null);
    }

    protected Object createNode(Object name, Object value) {
        return createNode(name, null, value);
    }

    protected Object createNode(Object name, Map attributes) {
        return createNode(name, attributes, null);
    }

    protected Object createNode(Object name, Map attributes, Object value) {

        try {
            if (state == OPENED_ELEMENT) {
                writer.append(">\n");
            }
            if (name.equals("text") && value != null) {
                writer.append(value.toString());
                state = TEXT_ELEMENT;
            } else {
                writer.append("<").append(name.toString());
                if (attributes != null) {
                    for (Object key : attributes.keySet()) {
                        writer.append(key.toString())
                                .append("=\"")
                                .append(attributes.get(key).toString())
                                .append("\"");
                    }
                }
                state = OPENED_ELEMENT;

                if (value != null) {
                    writer.append(">").append(value.toString());
                    state = CLOSED_ELEMENT;
                }
            }

            return name;
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    protected void nodeCompleted(Object parent, Object node) {
        try {
            switch (state) {
                case CLOSED_ELEMENT:
                    writer.append("</").append(node.toString()).append(">");
                    break;
                case OPENED_ELEMENT:
                    writer.append("/>");
                    break;

            }
            state = CLOSED_ELEMENT;
            writer.append("\n");
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }

}
